/*
**  SISTEMAS OPERATIVOS, 2C 2010
**  PRIMER TRABAJO PRACTICO
**  Simulacion de una colonia de hormigas.

**  File:       cmd.c
**  Content:    structures and functions for commands.
*/

#include "../include/cmd.h"

size_t CMD_SIZE[NUM_CMDS] = {
    sizeof(struct cmd_start_t),
    sizeof(struct cmd_turn_t),
    
    sizeof(struct cmd_move_req_t),
    sizeof(struct cmd_move_res_t),
    
    sizeof(struct cmd_smell_req_t),
    sizeof(struct cmd_smell_res_t),
    
    sizeof(struct cmd_pick_req_t),
    sizeof(struct cmd_pick_res_t),
    
    sizeof(struct cmd_aid_req_t),
    sizeof(struct cmd_aid_res_t),
    
    sizeof(struct cmd_yell_req_t),
    sizeof(struct cmd_yell_res_t),
    sizeof(struct cmd_yell_not_t),
    
    sizeof(struct cmd_stop_t)
};

/* CODE AUTO-GENERATED BY TOOLS/AUTOGEN.PY */
/* CREATION FUNCTIONS: */
cmd_t newYellNot(int row, int col) {
    cmd_yell_not_t ret = (cmd_yell_not_t) malloc(sizeof(struct cmd_yell_not_t));
    ret->type = CMD_YELL_NOT;
    ret->r = row;
    ret->c = col;
    
    return (cmd_t) ret;
}


cmd_t newYellReq() {
    cmd_yell_req_t ret = (cmd_yell_req_t) malloc(sizeof(struct cmd_yell_req_t));
    ret->type = CMD_YELL_REQ;
    
    
    return (cmd_t) ret;
}


cmd_t newYellRes() {
    cmd_yell_res_t ret = (cmd_yell_res_t) malloc(sizeof(struct cmd_yell_res_t));
    ret->type = CMD_YELL_RES;
    
    
    return (cmd_t) ret;
}


cmd_t newAidReq(int dir) {
    cmd_aid_req_t ret = (cmd_aid_req_t) malloc(sizeof(struct cmd_aid_req_t));
    ret->type = CMD_AID_REQ;
    ret->dir = dir;
    
    return (cmd_t) ret;
}


cmd_t newAidRes(int status) {
    cmd_aid_res_t ret = (cmd_aid_res_t) malloc(sizeof(struct cmd_aid_res_t));
    ret->type = CMD_AID_RES;
    ret->status = status;
    
    return (cmd_t) ret;
}


cmd_t newTurn() {
    cmd_turn_t ret = (cmd_turn_t) malloc(sizeof(struct cmd_turn_t));
    ret->type = CMD_TURN;
    
    
    return (cmd_t) ret;
}


cmd_t newStop() {
    cmd_stop_t ret = (cmd_stop_t) malloc(sizeof(struct cmd_stop_t));
    ret->type = CMD_STOP;
    
    
    return (cmd_t) ret;
}


cmd_t newSmellRes(tile_t tiles) {
    cmd_smell_res_t ret = (cmd_smell_res_t) malloc(sizeof(struct cmd_smell_res_t));
    ret->type = CMD_SMELL_RES;
    memcpy(ret->tiles, tiles, sizeof(struct tile_t) * 8);
    
    return (cmd_t) ret;
}


cmd_t newStart() {
    cmd_start_t ret = (cmd_start_t) malloc(sizeof(struct cmd_start_t));
    ret->type = CMD_START;
    
    
    return (cmd_t) ret;
}


cmd_t newSmellReq() {
    cmd_smell_req_t ret = (cmd_smell_req_t) malloc(sizeof(struct cmd_smell_req_t));
    ret->type = CMD_SMELL_REQ;
    
    
    return (cmd_t) ret;
}


cmd_t newPickRes(int status) {
    cmd_pick_res_t ret = (cmd_pick_res_t) malloc(sizeof(struct cmd_pick_res_t));
    ret->type = CMD_PICK_RES;
    ret->status = status;
    
    return (cmd_t) ret;
}


cmd_t newPickReq(int dir) {
    cmd_pick_req_t ret = (cmd_pick_req_t) malloc(sizeof(struct cmd_pick_req_t));
    ret->type = CMD_PICK_REQ;
    ret->dir = dir;
    
    return (cmd_t) ret;
}


cmd_t newMoveRes(int status) {
    cmd_move_res_t ret = (cmd_move_res_t) malloc(sizeof(struct cmd_move_res_t));
    ret->type = CMD_MOVE_RES;
    ret->status = status;
    
    return (cmd_t) ret;
}


cmd_t newMoveReq(int dir) {
    cmd_move_req_t ret = (cmd_move_req_t) malloc(sizeof(struct cmd_move_req_t));
    ret->type = CMD_MOVE_REQ;
    ret->dir = dir;
    
    return (cmd_t) ret;
}

handler_f* buildHandlerArray() {
    return (handler_f*) calloc(NUM_CMDS, sizeof(handler_f));
}

size_t cmdsize(cmd_t cmd) {
    return CMD_SIZE[cmd->type];
}

cmd_t dispatchCmd(void* obj, cmd_t cmd, handler_f* handlers) {

    if (cmd->type >= 0 && cmd->type < NUM_CMDS) {

        if (handlers[cmd->type] != NULL)
            return handlers[cmd->type](obj, cmd);
    }
    /* Invalid command type, or no handler specified for it: */
    return NULL;

}

int randDir() {
    return rand() % NUM_DIRS;
}

